package it.mauriziulu.android.ehttpexecutors;

import it.mauriziulu.android.ehttpexecutor.R;
import it.mauriziulu.android.ehttpexecutors.cache.CacheManager;
import it.mauriziulu.android.ehttpexecutors.cache.MemCacheManager;
import it.mauriziulu.android.ehttpexecutors.handler.ResponseHandlerChain;
import it.mauriziulu.android.ehttpexecutors.request.EHttpRequest;
import it.mauriziulu.android.ehttpexecutors.response.EHttpResponseContainer;
import it.mauriziulu.android.ehttpexecutors.util.SettingsUtil;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.impl.DefaultHttpRequestFactory;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

import android.content.Context;
import android.net.http.AndroidHttpClient;

/**
 * Main executor class. This is a singleton, access point to any http/s request.
 * 
 * @author m.basile
 * 
 */

public class BaseNetworkExecutor {

	public static final String IF_NONE_MATCH = "If-None-Match:";

	public static final String IF_MODIFIED_SINCE = "If-Modified-Since";

	protected static BaseNetworkExecutor mInstance;

	protected ExecutorService mExecutor;

	protected AndroidHttpClient mClient;

	protected DefaultHttpRequestFactory mRequestFactory;

	private HttpContext mHttpContext;

	private CacheManager mCacheManager;

	private Context mAndroidContext;

	protected BaseNetworkExecutor(Context context) {
		mAndroidContext = context;
		mExecutor = Executors.newFixedThreadPool(SettingsUtil.getInt(context, R.integer.EXECUTOR_NUM_THREAD));
		mClient = AndroidHttpClient.newInstance(SettingsUtil.getString(context, R.string.USER_AGENT), context);
		// TODO: Customizeable
		// mCacheManager = new FSCacheManager(context);
		mCacheManager = new MemCacheManager(context);
		mRequestFactory = new DefaultHttpRequestFactory();
		mHttpContext = new BasicHttpContext();
	}

	public static BaseNetworkExecutor getInstance(Context context) {
		if (mInstance == null) {
			mInstance = new BaseNetworkExecutor(context);
		}
		return mInstance;
	}

	public void call(EHttpRequest request, EHttpResponseContainer response, ResponseHandlerChain chain) throws ClientProtocolException, IOException {
		encrich(chain);
		chain.doHandle(request, response);
	}


	// public void get(CacheAwareResponseHandler responseHandler, HttpParams
	// params) throws ClientProtocolException, MalformedURLException,
	// MethodNotSupportedException, IOException {
	// String uri = responseHandler.getUrl();
	// CacheMetaEntry meta = mCacheManager.getMeta(uri);
	// responseHandler.setCacheManager(mCacheManager);
	// HttpRequest buildGetRequest = buildGetRequest(uri);
	// if (meta != null) {
	// buildGetRequest.addHeader(IF_MODIFIED_SINCE,
	// DateUtils.formatDate(meta.getDate()));
	// buildGetRequest.addHeader(IF_NONE_MATCH, meta.getETag());
	// }
	// if (params != null) {
	// buildGetRequest.setParams(params);
	// }
	// mClient.execute(buildTarget(uri), buildGetRequest, responseHandler,
	// mContext);
	// }

	private void encrich(ResponseHandlerChain chain) {
		if (chain.getCacheManager() == null) {
			chain.setCacheManager(mCacheManager);
		}
		if (chain.getClient() == null) {
			chain.setClient(mClient);
		}
		if (chain.getHttpContext() == null) {
			chain.setHttpContext(mHttpContext);
		}
		if (chain.getRequestFactory() == null) {
			chain.setRequestFactory(mRequestFactory);
		}
		if (chain.getAndroidContext() == null) {
			chain.setAndroidContext(mAndroidContext);
		}
	}

	
}
